﻿Imports System.Globalization
Imports System.Linq.Expressions
Imports System.Runtime.CompilerServices

''' <summary>Represents support for making selections in a list.</summary>
Public Module SelectExtensions2

    ''' <summary>Returns a single-selection select element using the specified HTML helper and the name of the form field.</summary>
    ''' <returns>An HTML select element.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, Nothing, Nothing, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, and the specified list items.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem)) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, selectList, Nothing, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, and an option label.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal optionLabel As String) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, Nothing, optionLabel, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, and the specified HTML attributes.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, selectList, Nothing, htmlAttributes)
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, and the specified HTML attributes.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As Object) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, selectList, Nothing, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, and an option label.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, selectList, optionLabel, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, an option label, and the specified HTML attributes.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String, ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Return DropDownList2Helper(htmlHelper, name, selectList, optionLabel, htmlAttributes)
    End Function

    ''' <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, an option label, and the specified HTML attributes.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function DropDownList2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String, ByVal htmlAttributes As Object) As MvcHtmlString
        Return htmlHelper.DropDownList2(name, selectList, optionLabel, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function DropDownList2For(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TProperty)), ByVal selectList As IEnumerable(Of SelectListItem)) As MvcHtmlString
        Return htmlHelper.DropDownList2For(Of TProperty)(expression, selectList, Nothing, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="htmlAttributes">A dictionary that contains the HTML attributes to set for the element.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function DropDownList2For(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TProperty)), ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Return htmlHelper.DropDownList2For(Of TProperty)(expression, selectList, Nothing, htmlAttributes)
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function DropDownList2For(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TProperty)), ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As Object) As MvcHtmlString
        Return htmlHelper.DropDownList2For(Of TProperty)(expression, selectList, Nothing, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and option label.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function DropDownList2For(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TProperty)), ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String) As MvcHtmlString
        Return htmlHelper.DropDownList2For(Of TProperty)(expression, selectList, optionLabel, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, option label, and HTML attributes.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <param name="htmlAttributes">A dictionary that contains the HTML attributes to set for the element.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function DropDownList2For(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TProperty)), ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String, ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        If expression Is Nothing Then
            Throw New ArgumentNullException("expression")
        End If
        Return DropDownList2Helper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, optionLabel, htmlAttributes)
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, option label, and HTML attributes.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    <Extension()> _
    Public Function DropDownList2For(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), ByVal expression As Expression(Of Func(Of TModel, TProperty)), ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String, ByVal htmlAttributes As Object) As MvcHtmlString
        Return htmlHelper.DropDownList2For(Of TProperty)(expression, selectList, optionLabel, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a multi-select select element using the specified HTML helper and the name of the form field.</summary>
    ''' <returns>An HTML select element.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function ListBox2(ByVal htmlHelper As HtmlHelper, ByVal name As String) As MvcHtmlString
        Return htmlHelper.ListBox2(name, Nothing, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a multi-select select element using the specified HTML helper, the name of the form field, and the specified list items.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function ListBox2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem)) As MvcHtmlString
        Return htmlHelper.ListBox2(name, selectList, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns a multi-select select element using the specified HTML helper, the name of the form field, the specified list items, and the specified HMTL attributes.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list..</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function ListBox2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Return ListBox2Helper(htmlHelper, name, selectList, htmlAttributes)
    End Function

    ''' <summary>Returns a multi-select select element using the specified HTML helper, the name of the form field, and the specified list items.</summary>
    ''' <returns>An HTML select element with an option subelement for each item in the list..</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="name">The name of the form field to return.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
    <Extension()> _
    Public Function ListBox2(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As Object) As MvcHtmlString
        Return htmlHelper.ListBox2(name, selectList, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression and using the specified list items.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the list.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function ListBox2For(Of TModel, TProperty)(
                                                         ByVal htmlHelper As HtmlHelper(Of TModel),
                                                         ByVal expression As Expression(Of Func(Of TModel, TProperty)),
                                                         ByVal selectList As IEnumerable(Of SelectListItem)) As MvcHtmlString
        Return htmlHelper.ListBox2For(Of TProperty)(expression, selectList, DirectCast(Nothing, IDictionary(Of String, Object)))
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the list.</param>
    ''' <param name="htmlAttributes">A dictionary that contains the HTML attributes to set for the element.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function ListBox2For(Of TModel, TProperty)(
                                                         ByVal htmlHelper As HtmlHelper(Of TModel),
                                                         ByVal expression As Expression(Of Func(Of TModel, TProperty)),
                                                         ByVal selectList As IEnumerable(Of SelectListItem),
                                                         ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        If expression Is Nothing Then
            Throw New ArgumentNullException("expression")
        End If
        Return ListBox2Helper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, htmlAttributes)
    End Function

    ''' <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
    ''' <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    ''' <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    ''' <param name="expression">An expression that identifies the object that contains the properties to render.</param>
    ''' <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the list.</param>
    ''' <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    ''' <typeparam name="TModel">The type of the model.</typeparam>
    ''' <typeparam name="TProperty">The type of the value.</typeparam>
    ''' <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
    <Extension()> _
    Public Function ListBox2For(Of TModel, TProperty)(
                                                         ByVal htmlHelper As HtmlHelper(Of TModel),
                                                         ByVal expression As Expression(Of Func(Of TModel, TProperty)),
                                                         ByVal selectList As IEnumerable(Of SelectListItem),
                                                         ByVal htmlAttributes As Object) As MvcHtmlString
        Return htmlHelper.ListBox2For(Of TProperty)(expression, selectList, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
    End Function

    Friend Function ListItemToOption(ByVal item As SelectListItem) As String
        Dim builder2 As New TagBuilder("option")
        builder2.InnerHtml = HttpUtility.HtmlEncode(item.Text)
        Dim builder As TagBuilder = builder2
        If item.Value IsNot Nothing Then
            builder.Attributes("value") = item.Value
        End If
        If item.Selected Then
            builder.Attributes("selected") = "selected"
        End If
        Return builder.ToString(TagRenderMode.Normal)
    End Function

    Private Function ListBox2Helper(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Return htmlHelper.SelectInternal(Nothing, name, selectList, True, htmlAttributes)
    End Function

    Private Function DropDownList2Helper(ByVal htmlHelper As HtmlHelper, ByVal expression As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal optionLabel As String, ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Return htmlHelper.SelectInternal(optionLabel, expression, selectList, False, htmlAttributes)
    End Function

    <Extension()> _
    Private Function GetSelectData(ByVal htmlHelper As HtmlHelper, ByVal name As String) As IEnumerable(Of SelectListItem)
        Dim obj2 As Object = Nothing
        If htmlHelper.ViewData IsNot Nothing Then
            obj2 = htmlHelper.ViewData.Eval(name)
        End If
        If obj2 Is Nothing Then
            Throw New InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.HtmlHelper_MissingSelectData, New Object() {name, "IEnumerable<SelectListItem>"}))
        End If
        Dim enumerable As IEnumerable(Of SelectListItem) = TryCast(obj2, IEnumerable(Of SelectListItem))
        If enumerable Is Nothing Then
            Throw New InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.HtmlHelper_WrongSelectDataType, New Object() {name, obj2.[GetType]().FullName, "IEnumerable<SelectListItem>"}))
        End If
        Return enumerable
    End Function

    <Extension()> _
    Private Function SelectInternal(ByVal htmlHelper__1 As HtmlHelper, ByVal optionLabel As String, ByVal name As String, ByVal selectList As IEnumerable(Of SelectListItem), ByVal allowMultiple As Boolean, ByVal htmlAttributes As IDictionary(Of String, Object)) As MvcHtmlString
        Dim state As ModelState = Nothing
        Dim shortName As String = name
        ' added
        name = htmlHelper__1.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name)
        If String.IsNullOrEmpty(name) Then
            Throw New ArgumentException(MvcResources.Common_NullOrEmpty, "name")
        End If
        Dim flag As Boolean = False
        If selectList Is Nothing Then
            ' changed
            ' selectList = htmlHelper.GetSelectData(name);
            selectList = htmlHelper__1.GetSelectData(shortName)
            flag = True
        End If
        Dim obj2 As Object = If(allowMultiple, htmlHelper__1.GetModelStateValue(name, GetType(String())), htmlHelper__1.GetModelStateValue(name, GetType(String)))
        If Not flag AndAlso (obj2 Is Nothing) Then
            ' changed
            ' obj2 = htmlHelper.ViewData.Eval(name);
            obj2 = htmlHelper__1.ViewData.Eval(shortName)
        End If
        If obj2 IsNot Nothing Then
            Dim source As IEnumerable = If(allowMultiple, TryCast(obj2, IEnumerable), DirectCast(New Object() {obj2}, IEnumerable))
            Dim mySet As New HashSet(Of String)(
                source.Cast(Of Object)().Select(Of String)(Function(value) Convert.ToString(value, CultureInfo.CurrentCulture)), StringComparer.OrdinalIgnoreCase)
            Dim list As New List(Of SelectListItem)()
            For Each item As SelectListItem In selectList
                item.Selected = If((item.Value IsNot Nothing), mySet.Contains(item.Value), mySet.Contains(item.Text))
                list.Add(item)
            Next
            selectList = list
        End If
        Dim builder As New StringBuilder()
        If optionLabel IsNot Nothing Then
            Dim item2 As New SelectListItem()
            item2.Text = optionLabel
            item2.Value = String.Empty
            item2.Selected = False
            builder.AppendLine(ListItemToOption(item2))
        End If
        For Each item3 As SelectListItem In selectList
            builder.AppendLine(ListItemToOption(item3))
        Next
        Dim builder3 As New TagBuilder("select")
        builder3.InnerHtml = builder.ToString()
        Dim builder2 As TagBuilder = builder3
        builder2.MergeAttributes(Of String, Object)(htmlAttributes)
        builder2.MergeAttribute("name", name, True)
        builder2.GenerateId(name)
        If allowMultiple Then
            builder2.MergeAttribute("multiple", "multiple")
        End If
        If htmlHelper__1.ViewData.ModelState.TryGetValue(name, state) AndAlso (state.Errors.Count > 0) Then
            builder2.AddCssClass(HtmlHelper.ValidationInputCssClassName)
        End If
        Return builder2.ToMvcHtmlString(TagRenderMode.Normal)
    End Function

#Region "Common"

    <Extension()> _
    Private Function GetModelStateValue(ByVal self As HtmlHelper, ByVal key As String, ByVal destinationType As Type) As Object
        Dim state As ModelState = Nothing
        If self.ViewData.ModelState.TryGetValue(key, state) AndAlso (state.Value IsNot Nothing) Then
            Return state.Value.ConvertTo(destinationType, Nothing)
        End If
        Return Nothing
    End Function

    <Extension()> _
    Private Function ToMvcHtmlString(ByVal self As TagBuilder, ByVal renderMode As TagRenderMode) As MvcHtmlString
        Return MvcHtmlString.Create(self.ToString(renderMode))
    End Function


#End Region
End Module
